<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html><head><title>Programming in Lua : 14.3</title>
<link rel="stylesheet" type="text/css" href="pil.css">
</head>
<body>
<p class="warning">
<A HREF="contents.html"><IMG TITLE="Programming in Lua (first edition)" SRC="capa.jpg" ALT="" ALIGN="left"></A>This first edition was written for Lua 5.0. While still largely relevant for later versions, there are some differences.<BR>The third edition targets Lua 5.2 and is available at <A HREF="http://www.amazon.com/exec/obidos/ASIN/859037985X/theprogrammil3-20">Amazon</A> and other bookstores.<BR>By buying the book, you also help to <A HREF="../donations.html">support the Lua project</A>.
</p>
<table width="100%" class="nav">
<tr>
<td width="10%" align="left"><a href="14.2.html"><img border="0" src="left.png" alt="Previous"></a></td>
<td width="80%" align="center"><a href="contents.html"><font face="Helvetica,Arial,sanserif">
<font color="gray">Programming in </font><font color="blue"> Lua</font>
</font></a></td>
<td width="10%" align="right"><a href="15.html"><img border="0" src="right.png" alt="Next"></a></td>
</tr>
<tr>
<td width="10%" align="left"></td>
<td width="80%" align="center"><a href="contents.html#P2">Part II. Tables and Objects</a>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="contents.html#14">Chapter 14. The Environment</a></td>
<td width="10%" align="right"></td></tr>
</table>
<hr/>
<p><h2>14.3 &ndash; Non-Global Environments</h2>

<p>One of the problems with the environment is that it is global.
Any modification you do on it affects all parts of your program.
For instance, when you install a metatable to control global access,
your whole program must follow the guidelines.
If you want to use a library that uses
global variables without declaring them,
you are in bad luck.

<p>Lua 5.0 ameliorates this problem by allowing each
function to have its own environment.
That may sound strange at first;
after all, the goal of a table of global variables is to be global.
However, in <a href="15.4.html#package-env">Section 15.4</a> we will see that this facility allows
several interesting constructions,
where global values are still available everywhere.

<p>You can change the environment of a function with the
<code>setfenv</code> function (<em>set function environment</em>).
It receives the function and the new environment.
Instead of the function itself,
you can also give a number,
meaning the active function at that given stack level.
Number 1 means the current function,
number 2 means the function calling the current function
(which is handy to write auxiliary functions that change
the environment of their caller),
and so on.

<p>A naive first attempt to use <code>setfenv</code> fails miserably.
The code
<pre>
    a = 1   -- create a global variable
    -- change current environment to a new empty table
    setfenv(1, {})
    print(a)
</pre>
results in
<pre>
    stdin:5: attempt to call global `print' (a nil value)
</pre>
(You must run that code in a single chunk.
If you enter it line by line in interactive mode,
each line is a different function
and the call to <code>setfenv</code> only affects its own line.)
Once you change your environment,
all global accesses will use this new table.
If it is empty, you lost all your global variables,
even <code>_G</code>.
So, you should first populate it with some useful values,
such as the old environment:
<pre>
    a = 1   -- create a global variable
    -- change current environment
    setfenv(1, {_G = _G})
    _G.print(a)      --> nil
    _G.print(_G.a)   --> 1
</pre>
Now, when you access the "global" <code>_G</code>,
its value is the old environment,
wherein you will find the field <code>print</code>.

<p>You can populate your new environment using inheritance also:
<pre>
    a = 1
    local newgt = {}        -- create new environment
    setmetatable(newgt, {__index = _G})
    setfenv(1, newgt)    -- set it
    print(a)          --> 1
</pre>
In this code,
the new environment inherits both <code>print</code> and <code>a</code> from
the old one.
Nevertheless, any assignment goes to the new table.
There is no danger of changing a really global variable by mistake,
although you still can change them through <code>_G</code>:
<pre>
    -- continuing previous code
    a = 10
    print(a)      --> 10
    print(_G.a)   --> 1
    _G.a = 20
    print(_G.a)   --> 20
</pre>

<p>When you create a new function,
it inherits its environment from the function creating it.
Therefore, if a chunk changes its own environment,
all functions it defines afterward will share this same environment.
This is a useful mechanism for creating namespaces,
as we will see in the next chapter.

<p>
<hr/>
<table width="100%" class="nav">
<tr valign="top">
<td width="90%" align="left">
<small>
  Copyright &copy; 2003&ndash;2004 Roberto Ierusalimschy.  All rights reserved.
</small>
</td>
<td width="10%" align="right"><a href="15.html"><img border="0" src="right.png" alt="Next"></a></td>
</tr>
</table>


</body></html>

